package cn.wlinker.video.monitor.utils;

import cn.hutool.core.date.DateTime;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * SSRC生成器
 *
 * @author gxsjx
 * @version 1.0
 * @date 2025/5/3
 * Copyright © wlinker.cn
 */
public class SsrcGenerator {
    /**
     * 生成十六进制的SSRC（同步源标识符）
     * <p>
     * 该方法基于给定的参数生成一个唯一的SSRC值，并将其转换为十六进制字符串形式
     * 主要用于在特定的场景下（如RTMP流媒体传输中），需要以十六进制形式表示SSRC时调用
     *
     * @param host      服务器主机名，用于生成SSRC的唯一性部分
     * @param channelNo 频道编号，进一步增强SSRC的唯一性
     * @param startTime 事件开始时间，与结束时间一起用于限定SSRC生成的时间范围
     * @param endTime   事件结束时间，与开始时间一起限定SSRC生成的时间范围
     * @return 返回生成的十六进制SSRC字符串，转换为大写形式
     */
    public static String generateHexSsrc(String host, Integer channelNo, DateTime startTime, DateTime endTime) {
        int ssrc = generateSsrc(host, channelNo, startTime, endTime);
        return Integer.toHexString(ssrc).toUpperCase();
    }

    /**
     * 生成同步源标识符（SSRC）
     *
     * @param host      设备主机名或IP地址，可能为null
     * @param channelNo 通道编号，可能为null
     * @param startTime 会议开始时间，可能为null
     * @param endTime   会议结束时间，可能为null
     * @return 生成的32位SSRC值
     * <p>
     * 此方法用于根据设备信息和会议时间生成一个唯一的SSRC，以确保在多媒体通信中标识同步源
     * 它通过拼接输入参数并对其进行SHA-256哈希来生成一个伪随机数，然后使用哈希值的前32位作为SSRC
     */
    public static int generateSsrc(String host, Integer channelNo, DateTime startTime, DateTime endTime) {
        // 处理空值
        host = (host != null) ? host : "";
        String channelNoStr = (channelNo != null) ? channelNo.toString() : "";
        String startTimeStr = (startTime != null) ? startTime.toString() : "N/A";
        String endTimeStr = (endTime != null) ? endTime.toString() : "N/A";
        // 拼接输入字符串
        String input = host + channelNoStr + startTimeStr + endTimeStr;

        try {
            // 使用 SHA-256 哈希
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hashBytes = digest.digest(input.getBytes());

            // 取前 4 字节（32 位）作为 SSRC
            return ((hashBytes[0] & 0xFF) << 24)
                    | ((hashBytes[1] & 0xFF) << 16)
                    | ((hashBytes[2] & 0xFF) << 8)
                    | (hashBytes[3] & 0xFF);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256 algorithm not found", e);
        }
    }

    public static void main(String[] args) {
        int ssrc = generateSsrc("example.com", 1, null, null);
        System.out.println("SSRC (十进制): " + ssrc);
        System.out.println("SSRC (十六进制): 0x" + Integer.toHexString(ssrc).toUpperCase());
    }
}